﻿using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Polaris.Common;
using Polaris.Common.RedisHelper;
using Polaris.Domain.Interfaces.Admin;
using Polaris.Domain.Model.DbEntity;
using Polaris.Domain.Model.Dto.Notes.Request;
using Polaris.Domain.Model.Dto.Notes.Response;
using Polaris.Domain.Model.Dto.Permissions.Response;
using Polaris.Domain.Model.Dto.Sys_User.Response;
using Polaris.Domain.Model.Entity.Base;
using Polaris.Domain.Model.Entity.Exception;
using Polaris.Domain.Repository.Interfaces;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace Polaris.Infrastructure.DomainService.Admin
{
    public class NotesService : INotes
    {
        private readonly IBaseRepository<Notes> _notes;
        private readonly string _baseKey = "notes:admin";

        public NotesService(IBaseRepository<Notes> notes)
        {
            _notes = notes;
        }

        /// <summary>
        /// 创建闲书
        /// </summary>
        /// <param name="create"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        /// <exception cref="CustomException"></exception>
        public async Task CreateNotes(CreateNotesInfoRequest create, Guid? userId)
        {
            try
            {
                var cacheKey = $"{_baseKey}:query:*";
                await RedisHelper.DeleteKeysByPatternAsync(cacheKey);
                var id = Guid.NewGuid();
                var notes = new Notes()
                {
                    Id = id,
                    Browse = 0,
                    Content = create.Content,
                    CreateBy = userId,
                    CreateTime = DateTime.Now,
                    Enable = create.Enable,
                    IsComments = create.IsComments,
                    IsPrivacy = create.IsPrivacy,
                    IsDelete = false,
                    IsRedFlag = create.IsRedFlag,
                    Like = 0,
                    Mood = create.Mood,
                    MoodIcon = create.MoodIcon,
                    Password = create.Password,
                    Title = create.Title,
                    Weather = create.Weather,
                    WeatherIcon = create.WeatherIcon,
                };
                await _notes.AddEntityAsync(notes);
                await _notes.CommitAsync();

                await Task.Delay(500);
                await RedisHelper.DeleteKeysByPatternAsync(cacheKey);
            }
            catch (Exception ex)
            {
                throw new CustomException(Domain.Model.Enum.ResultCode.FAIL, ex.Message);
            }
        }

        /// <summary>
        /// 获取闲书列表
        /// </summary>
        /// <param name="quyer"></param>
        /// <returns></returns>
        public async Task<PaginationInfo<NotesListResponse>> GetNotesList(NotesQueryRequest query)
        {
            try
            {
                var cacheKey = $"{_baseKey}:query:{query.Title}:page:{query.PageIndex}:size:{query.PageSize}";

                var redisData = await RedisHelper.GetPaginationAsync<NotesListResponse>(cacheKey);
                if (redisData != null)
                {
                    return redisData;
                }
                else
                {
                    int total = 0;
                    var data = await _notes.QueryAll(out total, query.PageIndex, query.PageSize, n => n.CreateTime, false, n => !n.IsDelete)
                        .Select(n => new NotesListResponse()
                        {
                            Id = n.Id.ToString(),
                            IsPrivacy = n.IsPrivacy,
                            Enable = n.Enable,
                            IsComments = n.IsComments,
                            IsRedFlag = n.IsRedFlag,
                            Title = n.Title,
                            Browse = n.Browse,
                            Like = n.Like,
                            Mood = n.Mood,
                            NotesUpdateTime = n.NotesUpdateTime,
                            Weather = n.Weather,
                        }).ToListAsync();

                    var result = ApiResult
                    .CreatePaginationInfo<NotesListResponse>(
                                                                PageIndex: query.PageIndex,
                                                                PageSize: query.PageSize,
                                                                Total: total,
                                                                Result: data
                                                             );
                    await RedisHelper.CachePaginationAsync(cacheKey, result);
                    return result;
                }
            }
            catch (Exception ex)
            {
                throw new CustomException(Domain.Model.Enum.ResultCode.FAIL, ex.Message);
            }
        }

        /// <summary>
        /// 根据获取闲书内容
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<string> GetNotesContentById(string id)
        {
            var cacheKey = $"{_baseKey}:count:id:{id}";

            var redisData = await RedisHelper.GetStringKeyAsync(cacheKey);
            if (redisData.HasValue)
            {
                return await RedisHelper.GetStringKeyAsync(cacheKey);
            }
            else
            {
                var data = await _notes.QueryAll(n => !n.IsDelete && n.Id.ToString() == id)
                                .Select(n => n.Content).FirstOrDefaultAsync();
                if (data != null)
                {
                    await RedisHelper.SetStringKeyAsync(cacheKey, data, TimeSpan.FromMinutes(5));
                }

                return data;
            }

        }

        /// <summary>
        /// 根据获取闲书
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<NotesInfoResponse> GetNotesById(string id)
        {
            var cacheKey = $"{_baseKey}:info:id:{id}";
            var redisData = await RedisHelper.GetStringKeyAsync(cacheKey);
            if (redisData.HasValue)
            {
                return JsonConvert.DeserializeObject<NotesInfoResponse>(redisData);
            }
            else
            {
                var data = await _notes.QueryAll(n => !n.IsDelete && n.Id.ToString() == id)
                               .Select(n => new NotesInfoResponse()
                               {
                                   Content = n.Content,
                                   Enable = n.Enable,
                                   Id = n.Id.ToString(),
                                   IsComments = n.IsComments,
                                   IsPrivacy = n.IsPrivacy,
                                   IsRedFlag = n.IsRedFlag,
                                   Mood = n.Mood,
                                   MoodIcon = n.MoodIcon,
                                   Password = n.Password,
                                   Title = n.Title,
                                   Weather = n.Weather,
                                   WeatherIcon = n.WeatherIcon,
                               }).FirstOrDefaultAsync();

                if (data != null)
                {
                    await RedisHelper.SetStringKeyAsync(cacheKey, JsonConvert.SerializeObject(data));
                }
                return data;
            }
        }

        /// <summary>
        /// 修改闲书
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task UpdateNotes(NotesInfoResponse update, Guid? userId)
        {
            try
            {
                var cacheKey = $"{_baseKey}:query:*";
                var key = $"{_baseKey}:info:id:{update.Id}";
                await RedisHelper.DeleteKeysByPatternAsync(cacheKey);
                var data = await _notes.QueryAll(n => !n.IsDelete && n.Id.ToString() == update.Id)
                    .FirstOrDefaultAsync();
                if (data == null)
                {
                    throw new CustomException(Domain.Model.Enum.ResultCode.NO_DATA, "未找到数据");
                }

                var isExist = await RedisHelper.KeyExistsAsync(key);
                if (isExist)
                {
                    await RedisHelper.KeyDeleteAsync(key);
                }

                data.IsComments = update.IsComments;
                data.Mood = update.Mood;
                data.Weather = update.Weather;
                data.WeatherIcon = update.WeatherIcon;
                data.MoodIcon = update.MoodIcon;
                data.IsPrivacy = update.IsPrivacy;
                if (data.IsPrivacy)
                {
                    data.Password = update.Password;
                }
                data.Content = update.Content;
                data.UpdateBy = userId;
                data.UpdateTime = DateTime.Now;
                data.Enable = update.Enable;
                data.IsRedFlag = update.IsRedFlag;
                data.Title = update.Title;
                _notes.UpdateEntity(data);
                await _notes.CommitAsync();

                await Task.Delay(500);
                await RedisHelper.DeleteKeysByPatternAsync(cacheKey);
                if (isExist)
                {
                    await RedisHelper.KeyDeleteAsync(key);
                }
            }
            catch (Exception ex)
            {
                throw new CustomException(Domain.Model.Enum.ResultCode.FAIL, ex.Message);
            }
        }

        /// <summary>
        /// 删除闲书
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteById(string id, Guid? userId)
        {
            try
            {
                var cacheKey = $"{_baseKey}:query:*";
                var key = $"{_baseKey}:info:id:{id}";
                await RedisHelper.DeleteKeysByPatternAsync(cacheKey);
                var data = await _notes.QueryAll(n => !n.IsDelete && n.Id.ToString() == id)
                    .FirstOrDefaultAsync();
                if (data == null)
                {
                    throw new CustomException(Domain.Model.Enum.ResultCode.NO_DATA, "未找到数据");
                }

                var isExist = await RedisHelper.KeyExistsAsync(key);
                if (isExist)
                {
                    await RedisHelper.KeyDeleteAsync(key);
                }


                data.UpdateBy = userId;
                data.UpdateTime = DateTime.Now;
                data.IsDelete = true;
                _notes.UpdateEntity(data);
                await _notes.CommitAsync();

                await Task.Delay(500);
                await RedisHelper.DeleteKeysByPatternAsync(cacheKey);
                if (isExist)
                {
                    await RedisHelper.KeyDeleteAsync(key);
                }
            }
            catch (Exception ex)
            {
                throw new CustomException(Domain.Model.Enum.ResultCode.FAIL, ex.Message);
            }
        }

    }
}
